package com.example.demo.service.exam.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.domain.CombineClause;
import com.example.demo.domain.SingleClause;
import com.example.demo.domain.exam.ExamClassRelation;
import com.example.demo.dto.ExamClassRelationDTO;
import com.example.demo.exception.ExceptionUtils;
import com.example.demo.mapper.ExamClassRelationMapper;
import com.example.demo.service.impl.BaseServiceImpl;
import com.example.demo.service.exam.ExamClassRelationService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

@Service
@RequiredArgsConstructor
public class ExamClassRelationServiceImpl extends BaseServiceImpl<ExamClassRelationMapper, ExamClassRelation> implements ExamClassRelationService {

    private final ExamClassRelationMapper mapper;

    @Override
    public void createExamClassRelations(ExamClassRelationDTO dto) {
        Long examClassId = dto.getClassId();
        List<Long> examUserIds = dto.getUserIds();
        this.valid(examClassId, examUserIds);
        List<ExamClassRelation> relations = new ArrayList<>();
        examUserIds.forEach(userId -> {
            ExamClassRelation relation = new ExamClassRelation();
            relation.setClassId(examClassId);
            relation.setUserId(userId);
            relations.add(relation);
        });
        super.saveBatch(relations);
    }

    @Override
    public void deleteExamClassRelationsByClassId(Long classId) {
        Optional.ofNullable(classId).orElseThrow(() -> ExceptionUtils.exception("考试班级不能为空"));
        QueryWrapper<ExamClassRelation> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(ExamClassRelation::getClassId, classId);
        mapper.delete(wrapper);
    }

    @Override
    public List<ExamClassRelation> getExamClassRelationsByUserId(Long userId) {
        Optional.ofNullable(userId).orElseThrow(() -> ExceptionUtils.exception("用户标识不能为空"));
        QueryWrapper<ExamClassRelation> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(ExamClassRelation::getUserId, userId);
        return mapper.selectList(wrapper);
    }

    private void valid(Long examClassId, List<Long> examUserIds) {
        if (examClassId == null) {
            throw ExceptionUtils.exception("考试班级标识不能为空");
        }
        if (CollectionUtils.isEmpty(examUserIds)) {
            throw ExceptionUtils.exception("人员标识不能为空");
        }
    }

    public boolean existRelation(Long userId, Long classId) {
        Optional.ofNullable(userId).orElseThrow(() -> ExceptionUtils.exception("用户标识不能为空"));
        Optional.ofNullable(classId).orElseThrow(() -> ExceptionUtils.exception("班级标识不能为空"));
        CombineClause clauses = CombineClause.and(
                SingleClause.equal("class_id", classId),
                SingleClause.equal("user_id", userId)
        );
        return super.exists(clauses);
    }

    @Override
    public List<ExamClassRelation> getExamClassRelationsByClassId(Long classId) {
        Optional.ofNullable(classId).orElseThrow(() -> ExceptionUtils.exception("班级标识不能为空"));
        QueryWrapper<ExamClassRelation> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(ExamClassRelation::getClassId, classId);
        return mapper.selectList(wrapper);
    }

    @Override
    public void deleteByClassUserId(ExamClassRelationDTO dto) {
        Long classId = Optional.ofNullable(dto.getClassId()).orElseThrow(() -> ExceptionUtils.exception("班级标识不能为空"));
        List<Long> userIds = dto.getUserIds();
        if (CollectionUtils.isEmpty(userIds)){
            return;
        }
        super.delete(CombineClause.and(
                SingleClause.equal("class_id", classId),
                SingleClause.in("user_id", userIds.toArray(new Object[0]))
        ));
    }

    @Override
    public List<ExamClassRelation> getByClassIds(List<Long> classIds) {
        if (CollectionUtils.isEmpty(classIds)) {
            return Collections.emptyList();
        }
        return selectList(SingleClause.in("class_id", classIds.toArray(new Object[0])));
    }
}
